iT邦幫忙

2021 iThome 鐵人賽

DAY 17
1
Modern Web

React.js 30 天學習全記錄系列 第 17

[ Day 17 ] React 中的事件處理

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20211002/20134153HlJA85ahvZ.png
結束了 React Hooks 的章節之後,今天要進入到網頁互動少不了的事件處理部分了。 在 React.js 當中針對 DOM 事件處理的方式和原本 JavaScript 的寫法上會有什麼差異呢?


撰寫差異

一起來看看官網的範例,如果是採用 HTML 來撰寫事件處理的方式:

<button onclick="activateLasers()">
  Activate Lasers
</button>

我們可以在 HTML 當中使用使用事件處理的 onclick 方法,並賦予他對應處理的 Function 函式。

但如果是在 React.js 當中,我們就要改寫成下面範例程式碼:

<button onClick={activateLasers}>
  Activate Lasers
</button>

透過上面範例程式碼可以發現 JSX 和原本 HTML 撰寫不一樣的地方:

  1. 處理事件的名稱是採用 駝峰式命名( camelCase ) 的方式。
  2. 賦予該事件的值是一個 {} 包起來的 JavaScript Function

另外除了寫法上的差異之外,其實 React.js 對於事件的處理是採用一層叫做 SyntheticEvent 合成事件的處理機制。

Synthetic Events

React.js 採用 W3C 標準所撰寫的一個事件處理物件,具備了跨瀏覽器以及效能優化等功能所以能夠用更簡易的語法來處理事件的相關行為。

所以我們在處理某些事件的時候就需要採用 不同於原生事件( Native Event ) 的寫法,下面就給大家看一個範例:

/* HTML 寫法 */
<form onsubmit="console.log('You clicked submit.'); return false">
  <button type="submit">Submit</button>
</form>

在範例程式碼中,我們要避免觸發瀏覽器的預設行為:點擊後開啟新分頁,這時可以使用 return false 加在 onsubmit 這個事件處理之後就會達到需要的效果。

但如果要在 React.js 中移除掉瀏覽器本身的預設行為的話,就要採用另一種的撰寫方式:

function Form() {
  function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

在上面的 Function Component 中我們一定要使用 e.preventDefault() 這個方法來做阻擋該瀏覽器的行為,不能使用上面 Native Event 的寫法。
要特別注意元件裡面的 e 這個 event 並不是原本的 Native Event 而是上面提到的 Synthetic Event ,所以記得使用上會使有差異的。

備註:關於 e.preventDefault() 這個方法不熟悉的話,可以參考 Kuro 大大的這邊文章:重新認識 JavaScript: Day 15 隱藏在 "事件" 之中的秘密


事件綁定和傳值

事件處理方法的綁定

在官網當中還有特別提到,如果使用 Class 的元件在事件處理上是沒有預先使用 bind 語法做好綁定的話,就會發生取值產生 undefined 的狀況,這邊我們就直接看範例:

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 為了讓 `this` 能在 callback 中被使用,這裡的綁定是必要的:
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

這邊使用官網的範例 CodePen,該範例想要實現監聽按鈕的點擊事件然後變更按鈕上方的文字是 ON 或是 OFF 。

在上方的範例中我們在 constructor() 中初始化資料並綁定在這個元件實體上,這樣在 render() 回傳的 JSX 當中才能確實的使用到該 handleClick() 的函式。

透過事件處理傳遞參數

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

在處理陣列資料或是迴圈時,我們通常會需要傳遞額外的參數給事件處理的函式。因此在上面的範例中使用了箭頭函式的第一行程式碼需要帶入 id 參數之外也必須將 event 第二個參數 e 一同寫入,這樣才能確實的傳入。
但如果是採用第二行的 bind 綁定語法的話就不需要額外傳遞 event 的參數,因爲綁定過後的所有參數都會被確實的傳遞到該函式內。


React.js 中的 Event Handle 事件處理的一些簡介和用法就先為大家介紹到這邊了。這個章節會是我們寫 React.js 開發時不可或缺的功能,大家可以多看幾遍了解原理跟細節唷!
明天要跟大家介紹的是條件渲染,雖然我現在也還不知道那是什麼(?
那我們就下篇見ʘ‿ʘ


上一篇
[ Day 16 ] React Hooks 中的 useEffect
下一篇
[ Day 18 ] 條件 Render - Conditional Rendering
系列文
React.js 30 天學習全記錄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言